﻿using Digitalmes.Core.Common.Extensions;
using Digitalmes.Infrastructure.Jobs;
using Quartz;

namespace Digitalmes.Infrastructure;

/// <summary>
/// Job DI 注入。
/// </summary>
public static class JobDIExtensions
{
    /// <summary>
    /// 注入 Quartz Job 服务。
    /// </summary>
    /// <param name="services"></param>
    /// <param name="configuration"></param>
    /// <param name="name"></param>
    /// <returns></returns>
    public static IServiceCollection AddJobSetup(this IServiceCollection services, IConfiguration configuration, string name = "Quartz")
    {
        services.Configure<QuartzOptions>(configuration.GetSection(name));

        services.AddQuartz(q =>
        {
            q.UseSimpleTypeLoader();
            q.UseInMemoryStore();
            q.UseDefaultThreadPool(tp => tp.MaxConcurrency = 10);

            var jobTypes = typeof(DependencyInjection).Assembly.GetAllAttributesOf<JobScheduleAttribute>();
            foreach (var jobType in jobTypes)
            {
                var attr = jobType.GetCustomAttribute<JobScheduleAttribute>()!;

                // AddJob() + AddTrigger() 等同于 ScheduleJob<>()
                JobKey jobKey = new(attr.Identity, attr.Group);
                q.AddJob(jobType, jobKey);
                q.AddTrigger(trigger => trigger
                    .ForJob(jobKey)
                    .StartNow()
                    .WithCronSchedule(attr.Cron)
                    .WithDescription(attr.Description)
                );
            }
        });

        services.AddQuartzHostedService(options =>
        {
            // when shutting down we want jobs to complete gracefully
            options.WaitForJobsToComplete = true;
        });

        return services;
    }
}
